Conversation
- Create Blazor/ folder with BlazorAuthenticationChallengeHandler and LoginLogoutEndpointRouteBuilderExtensions - Add comprehensive XML documentation with remarks for Blazor Server scenarios - Update PublicAPI.Unshipped.txt for net8.0, net9.0, and net10.0 - Add AOT/trimming attributes (RequiresUnreferencedCode, RequiresDynamicCode) - Exclude Blazor folder from .NET Framework and netstandard2.0 builds Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com>
- Create BlazorAuthenticationChallengeHandlerTests with 7 passing tests - Create LoginLogoutEndpointRouteBuilderExtensionsTests with 11 passing tests (placeholder tests for integration test coverage) - Tests validate GetUserAsync, IsAuthenticatedAsync, and HandleExceptionAsync behavior - Skip 2 tests requiring NavigationManager initialization (covered in integration tests) Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com>
- Replace 11 placeholder tests with single test verifying extension method exists - Add comprehensive documentation comment explaining integration test requirements - All tests pass (5 passed, 2 skipped) Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com>
- Create AspireBlazorCallsWebApi solution with 4 projects - AppHost: Aspire orchestration for service discovery - ServiceDefaults: Shared configuration for observability - ApiService: Protected API with weather endpoint - Web: Blazor Server app with authentication and API calls Features demonstrated: - Blazor Server with Microsoft Identity authentication - BlazorAuthenticationChallengeHandler for incremental consent - MapLoginAndLogout extension for OIDC endpoints - Protected API calls with token acquisition - Aspire service orchestration and discovery - OpenTelemetry integration Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com>
- Document project structure and features - Provide running instructions for VS and CLI - Explain authentication configuration - Show code highlights for key patterns - Include architecture diagram - Link to relevant documentation Co-authored-by: jmprieur <13203188+jmprieur@users.noreply.github.com>
I used .NET 9 with Aspire 9.0.0 for stability and compatibility reasons:
The DevApp can easily be upgraded to .NET 10 once Aspire 10.0.0 stable is released by simply updating the |
src/Microsoft.Identity.Web/Blazor/BlazorAuthenticationChallengeHandler.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/BlazorAuthenticationChallengeHandler.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/LoginLogoutEndpointRouteBuilderExtensions.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/BlazorAuthenticationChallengeHandler.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/LoginLogoutEndpointRouteBuilderExtensions.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/LoginLogoutEndpointRouteBuilderExtensions.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/LoginLogoutEndpointRouteBuilderExtensions.cs
Show resolved
Hide resolved
src/Microsoft.Identity.Web/Blazor/LoginLogoutEndpointRouteBuilderExtensions.cs
Show resolved
Hide resolved
bgavrilMS
left a comment
There was a problem hiding this comment.
I tested this and it works.
|
@bgavrilMS you approved but did not merge, can we please get this merged? We have missed 2 release cycles already and this is blocking critical work for the Aspire team. Thanks. |
|
Changes looks good for me, only one thing, we could probably consider in future extracting Blazor functionality to other project (e.g., |
|
Then you will need to also extract AddMicrosoftIdentityWebApp and a bunch of classes. And this would require a major version change |
Adds
AspireBlazorCallsWebApiDevApp to demonstrateBlazorAuthenticationChallengeHandlerandMapLoginAndLogout()in a complete Aspire-orchestrated scenario.Structure
4-project solution:
AppHost: Aspire orchestration with service discoveryServiceDefaults: OpenTelemetry, health checks, resilienceApiService: Protected/weatherforecastendpoint requiring authenticationWeb: Blazor Server with Microsoft Identity authenticationKey Implementations
Incremental consent pattern in Weather.razor:
Authentication setup in Web/Program.cs:
Complete Blazor component structure:
App.razorwith Blazor Web JSRoutes.razorwithAuthorizeRouteViewUserInfo.razorshowing login/logout stateWeather.razordemonstrating API calls with challenge handlingMainLayout,NavMenu)Configuration
Uses test lab credentials matching
WebAppCallsWebApiCallsGraphDevApp:a021aff4-57ad-453a-bae8-e4192e5860f3a599ce88-0a5f-4a6e-beca-e67d3fc427f410c419d4-4a50-45b2-aa4e-919fb84df24fBuild succeeds on .NET 9.0. README included with architecture, running instructions, and code highlights.
Original prompt
Goal
Integrate
BlazorAuthenticationChallengeHandlerandLoginLogoutEndpointRouteBuilderExtensionsfrom.github/skills/entra-id-aspire-authentication/into the mainMicrosoft.Identity.WebNuGet package.Tasks
1. Create new Blazor subfolder and move files
Create
src/Microsoft.Identity.Web/Blazor/folder with these files (copy from.github/skills/entra-id-aspire-authentication/):BlazorAuthenticationChallengeHandler.cs- Handles authentication challenges for Blazor Server components (incremental consent, Conditional Access)LoginLogoutEndpointRouteBuilderExtensions.cs- Extension methodMapLoginAndLogout()for OIDC endpointsKeep the namespace as
Microsoft.Identity.Web(already correct in source files).Add XML doc
<remarks>noting these are for Blazor Server scenarios.2. Unit Tests
Create
tests/Microsoft.Identity.Web.Test/Blazor/folder with:BlazorAuthenticationChallengeHandlerTests.cs- Test:GetUserAsyncreturns ClaimsPrincipal from AuthenticationStateProviderIsAuthenticatedAsyncreturns correct bool based on identity stateHandleExceptionAsyncdetectsMicrosoftIdentityWebChallengeUserException(and as InnerException)ChallengeUserbuilds correct URL with scopes, loginHint, domainHint, claims parametersGetLoginHintextracts from "preferred_username" or "login_hint" claimsGetDomainHintreturns "consumers" for MSA tenant, "organizations" otherwiseLoginLogoutEndpointRouteBuilderExtensionsTests.cs- Test:/loginendpoint sets correct AuthProperties with scope, loginHint, domainHint, claims/logoutendpoint signs out from both Cookie and OIDC schemesGetAuthPropertiesvalidates returnUrl (prevents open redirects, handles relative/absolute URLs)3. Create minimal Aspire DevApp
Create
tests/DevApps/AspireBlazorCallsWebApi/with this structure:Credentials to use (reuse from WebAppCallsWebApiCallsGraph DevApp):
For API (
AspireBlazorCallsWebApi.ApiService/appsettings.json):{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "id4slab1.onmicrosoft.com", "TenantId": "10c419d4-4a50-45b2-aa4e-919fb84df24f", "ClientId": "a021aff4-57ad-453a-bae8-e4192e5860f3", "Scopes": "access_as_user" } }For Web App (
AspireBlazorCallsWebApi.Web/appsettings.json):{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "id4slab1.onmicrosoft.com", "TenantId": "10c419d4-4a50-45b2-aa4e-919fb84df24f", "ClientId": "a599ce88-0a5f-4a6e-beca-e67d3fc427f4", "CallbackPath": "/signin-oidc", "ClientCertificates": [ { "SourceType": "StoreWithDistinguishedName", "CertificateStorePath": "LocalMachine/My", "CertificateDistinguishedName": "CN=LabAuth.MSIDLab.com" } ] }, "WeatherApi": { "Scopes": ["api://a021aff4-57ad-453a-bae8-e4192e5860f3/access_as_user"] } }Key implementation points for DevApp:
AddMicrosoftIdentityWebApi+RequireAuthorization()on/weatherforecastendpointAddMicrosoftIdentityWebApp+EnableTokenAcquisitionToCallDownstreamApi+AddInMemoryTokenCachesBlazorAuthenticationChallengeHandleras scoped serviceWeatherApiClientHttpClient withAddMicrosoftIdentityMessageHandler/authenticationgroup withMapLoginAndLogout()ChallengeHandler.HandleExceptionAsync()patternAuthorizeRouteView4. Important Notes
.github/skills/entra-id-aspire-authentication/SKILL.md- that will be done post-releasedocs/frameworks/aspire.mdreferences to "copy from skill folder" - that will be done post-releaseReferences
This pull request was created from Copilot chat.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.